#include "mytcpsocket.h"

//由那个socket产生的数据们就由那个socket处理
MyTcpSocket::MyTcpSocket()
{
    connect(this,SIGNAL(readyRead()),this,SLOT(recvmsg()));
    connect(this,SIGNAL(disconnected()),this,SLOT(clientOffline()));
}

void MyTcpSocket::recvmsg()
{
    uint uiPDULen=0;
    this->read((char*)&uiPDULen,sizeof(uint));
    uint uiMsgLen =uiPDULen-sizeof(PDU);
    PDU *pdu=mkPDU(uiMsgLen);
    this->read((char*)pdu+sizeof(uint),uiPDULen-sizeof(uint));
    //qDebug()<<pdu->uiMsgType<<" "<<pdu->uiMsgLen<<" "<<pdu->caMsg;
    switch(pdu->uiMsgType)
    {
    case ENUM_MSG_TYPE_REGIST_REQUEST:
    {
        //用户注册数据库处理
        char name[32]={'\0'};
        char pwd[32]={'\0'};
        strncpy(name,pdu->odata,32);
        strncpy(pwd,pdu->odata+32,32);
        qDebug()<<name<<" "<<pwd<<" "<<pdu->uiMsgType;
        bool ret = DB::getinstance().handleRegis(name,pwd);
        PDU *pdu_res = mkPDU(0);
        pdu_res->uiMsgType=ENUM_MSG_TYPE_REGIST_RESPOND;
        if(ret)
        {
            //注册回应pdu
            strcpy(pdu_res->odata,REGIST_OK);
        }
        else
        {
            strcpy(pdu_res->odata,REGIST_FAILED);
        }
        write((char*)pdu_res,pdu_res->uiPDULen);
        free(pdu_res);
        pdu_res=NULL;
        break;
    }
    case ENUM_MSG_TYPE_LOGIN_REQUEST:
    {
        //用户登录数据库处理
        char name[32]={'\0'};
        char pwd[32]={'\0'};
        strncpy(name,pdu->odata,32);
        strncpy(pwd,pdu->odata+32,32);
        qDebug()<<name<<" "<<pwd<<" "<<pdu->uiMsgType;
        bool ret = DB::getinstance().handleLogin(name,pwd);
        PDU *pdu_res = mkPDU(0);
        pdu_res->uiMsgType=ENUM_MSG_TYPE_LOGIN_RESPONSE;
        if(ret)
        {
            //登录回应pdu
            strcpy(pdu_res->odata,LOGIN_OK);
            m_username=name;

        }
        else
        {
            strcpy(pdu_res->odata,LOGIN_FAILED);
        }
        write((char*)pdu_res,pdu_res->uiPDULen);
        free(pdu_res);
        pdu_res=NULL;
        break;
    }
    case ENUM_MSG_TYPE_ALL_ONLINE_USER_REQUEST:
    {
        //服务器进行查询数据库
        QStringList ret = DB::getinstance().handleAllUser();
        //将查询到的数据写入到pdu中，发送到客户端
        PDU* pdu = mkPDU(ret.size()*32);
        for(int i=0;i<ret.size();i++)
        {
            QString tmp = ret[i];
            memcpy(pdu->caMsg+i*32,tmp.toStdString().c_str(),tmp.size());
            tmp.clear();
        }
        pdu->uiMsgType=ENUM_MSG_TYPE_ALL_ONLINE_USER_RESPONSE;
        write((char*)pdu,pdu->uiPDULen);
        break;
    }
    case ENUM_MSG_TYPE_SEARCH_USER_REQUEST:
    {
        //服务器进行查询数据库
        char name[32]={0};
        memcpy(name,pdu->odata,32);
        int ret = DB::getinstance().handleSearchUsr(name);
        PDU* pdu = mkPDU(0);
        pdu->uiMsgType=ENUM_MSG_TYPE_SEARCH_USER_RESPONSE;
        memcpy(pdu->odata,&ret,sizeof(int));
        write((char*)pdu,pdu->uiPDULen);
        break;
    }
    default:
        break;
    }
    free(pdu);
    pdu=NULL;

}

//客户端退出，连接断开，服务收到disconnect信号，该槽函数与disconnect信号关联
void MyTcpSocket::clientOffline()
{
    qDebug()<<m_username;
    //调用数据库处理sql语句
    DB::getinstance().handleoffline(m_username.toStdString().c_str());
    //将链表中的客户端连接删除
    //1、发送信号到server，server将客户端连接从链表中删除
    emit offline(this);

}















